package com.fishingwithme.android.data.model

import com.google.gson.annotations.SerializedName
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

const val COMPONENT_TARGET: String = "C"

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class Fish(
    val code: String,
    val type: Int,
    val name: String
)

@Serializable
@OptIn(InternalSerializationApi::class)
data class City(
    val cityCode: String,
    val city: String? = null // Backend returns 'city' field, not 'cityName'
) {
    // Compatibility property for existing code
    val cityName: String? get() = city
}

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class BaseInfo(
    val code: String,
    val type: Int,
    val name: String
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class Position(
    val latitude: Double,
    val longitude: Double
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class CityLocation(
    val city: City? = null,
    val location: Position? = null
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Credit System
@Serializable
data class CreditAvailable(
    val isFulfill: Int,
    val creditVal: Int,
    val difference: Int,
    val ruleCredit: Int,
    val availableCredit: Int
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class UserCredit(
    val currentLevel: Int,
    val currentLevelName: String,
    val nextLevel: Int,
    val nextLevelName: String,
    val totalPoints: Int,
    val currentLevelPoints: Int,
    val nextLevelPoints: Int,
    val progressPercentage: Float,
    val remainingPoints: Int,
    val recentRecords: List<PointsRecord>,
    val autoSkipAds: Int
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class CreditAction(
    var autoSkipAds: Int
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class CreditLevelRule(
    val levelId: String? = null,
    val levelName: String? = null,
    val minPoints: Int? = null,
    val maxPoints: Int? = null,
    val coreTrait: String? = null,
    val upgradeThreshold: String? = null,
    val uri: String? = null,
    val createdAt: String? = null,
    val updatedAt: String? = null
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class PointsRecord(
    val id: String,
    val userId: String,
    val reason: String,
    val bizId: String,
    val point: Int,
    val createdDate: String,
    val createdBy: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class RuleItem(
    val id: Int,
    val levelRangeStart: Int,
    val levelRangeEnd: Int,
    val behaviorDesc: String,
    val points: Int,
    val limitDesc: String,
    val sortOrder: Int,
    val createdAt: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class ApproveRuleItem(
    val id: String,
    val name: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Comment System
@Serializable
data class Comment(
    val id: String? = null,
    val userId: String,
    val userName: String,
    val userAvatar: String,
    val content: String,
    val createTime: String? = null,
    val likeCount: Int? = null,
    val isLiked: Boolean? = null,
    val targetType: String,
    val targetId: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Fishing Records
@Serializable
data class FishingRecord(
    val id: String,
    val spotId: String,
    val fisherId: String,
    val fishes: List<Fish>,
    val harvestType: String,
    val harvestTypeVal: BaseInfo,
    val isRec: Int,
    val score: Int,
    val scoreVal: BaseInfo,
    val fishingAt: String,
    val jsonHisPictures: List<String>,
    val avatarUrl: String,
    val nickName: String,
    val lvl: Int,
    val lvlName: String,
    val comment: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Spot Related Models
@Serializable
data class Spot(
    val id: String,
    val name: String,
    val latitude: Double? = null,
    val longitude: Double? = null,
    val cityCode: String? = null,
    val isFree: Int? = null,
    val isPrivate: Int? = null
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class MySpotDto(
    @SerialName("id") val id: String,
    @SerialName("cityCode") val cityCode: String,
    @SerialName("city") val city: String,
    @SerialName("longitude") val longitude: Double,
    @SerialName("latitude") val latitude: Double,
    @SerialName("name") val name: String,
    @SerialName("lvl") val lvl: BaseInfo,
    @SerialName("pictures") val pictures: List<String>,
)

data class SpotApprovalDto(
    @SerialName("id") val id: String,
    @SerialName("longitude") val longitude: Double,
    @SerialName("latitude") val latitude: Double,
    @SerialName("name") val name: String,
    @SerialName("createdAt") val createdAt: String,
    @SerialName("disabled") val isCollected: Int
)

data class MyHarvestDto(
    val id: String,
    val spotId: String,
    val fishes: List<BaseInfo>,
    val harvestType: BaseInfo,
    val fishingAt: String,
    val pictures: List<String>
)

data class MyCircleDto(
    var id: String,
    var title: String,
    var points: List<Position>,
    var pics: List<String>,
    var maintainStatus:Int,
    var isActive: Int,
    var city:String
)

data class Auditor(
    @SerialName("id") val id: String,
    @SerialName("circleId") val circleId: String,
    @SerialName("circleName") val circleName: String,
    @SerialName("userId") val userId: String,
    @SerialName("nickname") val nickname: String
)


@OptIn(InternalSerializationApi::class)
@Serializable
data class SpotAddDTO(
    val circleId: Long,
    val name: String,
    val location: Position,

    val line: List<Position>,

    val pics: List<String>,

    val spotTypes: List<String>,

    val fishTypes: List<String>,

    val isFree: Boolean,

    val parkingEasy: Boolean,

    val lvl: String,

    val distance: String,

    val secret: Boolean,
    val isForbidden: Boolean,

    val waterType: String,

    val description: String
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class SpotUpdateDTO(
    val id: String,
    val name: String,
    val location: Position,

    val line: List<Position>,

    val pics: List<String>,

    val spotTypes: List<String>,

    val fishTypes: List<String>,

    val isFree: Boolean,

    val parkingEasy: Boolean,

    val lvl: String,

    val distance: String,

    val secret: Boolean,
    val isForbidden: Boolean,

    val waterType: String,

    val description: String
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class SpotDetail(
    val spotId: String,
    val name: String,
    val description: String,
    val latitude: Double,
    val longitude: Double,
    val cityCode: String? = null,
    val isFree: Int,
    val isPrivate: Int,
    val isForbidden: Int,
    val disabled: Int,
    val parkingEasy: Int,
    val createdBy: String,
    val createdByName: String,
    val updatedAt: String,
    val location: Position,
    val distance: BaseInfo,
    val lvl: BaseInfo,
    val waterType: BaseInfo,
    val jsonFishTypes: List<Fish>,
    val jsonSpotTypes: List<BaseInfo>,
    val jsonPics: List<String>
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class SpotProperty(
    val lvls: List<BaseInfo> = listOf(),
    val waterTypes: List<BaseInfo> = listOf(),
    val fishTypes: List<BaseInfo> = listOf(),
    val spotTypes: List<BaseInfo> = listOf(),
    val distances: List<BaseInfo> = listOf()
)


@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class MarkerCustomData(
    val polygonId: Int,
    val originId: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class Line(
    val id: String,
    val name: String,
    val longitude: Double,
    val latitude: Double,
    val isFree: Integer?,
    val isParkingConvenient: Integer?,
    val isPrivate: Integer?,
    val city: String?,
    val line: List<Position>,
    val distanceVal: BaseInfo?
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Polygon Models
@Serializable
data class PolygonOrigin(
    val city: String,
    val cityCode: String,
    val id: String,
    val isActive: Boolean,
    val latitude: Double,
    val longitude: Double,
    val points: List<Position>,
    val title: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class Polygon(
    val id: Int,
    val origin: PolygonOrigin? = null,
    val points: List<Position>,
    val strokeColor: String,
    val strokeWidth: Int,
    val fillColor: String? = null,
    val zIndex: Int,
    val isHighlighted: Boolean
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// User Models
@Serializable
data class UserInfo(
    val nickName: String,
    val avatarUrl: String,
    val password: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class User(
    val id: String,
    val username: String,
    var nickname: String?,
    val avatarUrl: String,
    val roles: List<String> = listOf(),
    val hasLogin: Boolean,
    val isLogging: Boolean
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class LoginUserDto(
    val id: String,
    val username: String,
    val nickname: String,
    val avatarUrl: String,
    val roles: List<String>,
    val hasLogin: Boolean,
    val isLogging: Boolean,
    val token: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class Fisher(
    val id: String,
    val name: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Circle and Messaging
@Serializable
data class HarvestData(
    val code: String,
    val type: Int,
    val name: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class HarvestContent(
    @SerializedName("id")
    val id: Long,  // 使用Long因为数值较大
    @SerializedName("pics")
    val pictures: List<String>,
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class SpotContent(
    @SerializedName("id")
    val id: Long,  // 使用Long因为数值较大
    @SerializedName("pics")
    val pictures: List<String>,  // 包含JSON数组的字符串
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class CircleMessage<T>(
    val id: String,
    val cityCode: String,
    val messageType: String,
    val subtype: String,
    val content: T,
    val timestamp: String,
    val priority: Int = 1,
    val cursor: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Enums
enum class ViewSpotType {
    VISIT,
    XIAGAN,
    SHANGYU,
    MSG
}

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class FishingMessage(
    val type: ViewSpotType,
    val msg: String
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
// Generic Response Wrapper
@Serializable
data class ApiResponse<T>(
    val data: T,
    val status: Int, // Changed from Boolean to Int to match backend (1/0)
    val msg: String,
    val code: Int
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class ApiAuthResponse<T>(
    val data: T,
    val status: Boolean, // Changed from Boolean to Int to match backend (1/0)
    val msg: String,
    val code: Int
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class PageResponse<T>(
    val records: List<T>? = listOf(),
    val total: Int? = 0,
    val size: Int? = 0,
    val current: Int? = 0,
    val pages: Int? = 0
)

@OptIn(InternalSerializationApi::class) // Basic Data Models
@Serializable
data class HarvestSubmission(
    val visitId: String,
    val spotId: String,
    val pictures: List<String>,
    val isRec: Boolean,
    val harvestType: String,
    val score: String,
    val comment: String,
    val cityCode: String?,
    val fishes: List<String>
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class Agr(
    // 创建时间（格式：yyyy-MM-dd HH:mm:ss）
    @SerialName("createdAt")
    val createdAt: String,

    // 更新时间（格式：yyyy-MM-dd HH:mm:ss）
    @SerialName("updatedAt")
    val updatedAt: String,

    // 创建者ID
    @SerialName("createdBy")
    val createdBy: String,

    // 更新者ID
    @SerialName("updatedBy")
    val updatedBy: String,

    // 实体唯一标识
    @SerialName("id")
    val id: String,

    // 类型标识（如"UA"）
    @SerialName("type")
    val type: String,

    // 内容（可为空字符串）
    @SerialName("content")
    val content: String,

    // 版本号
    @SerialName("ver")
    val ver: Int,

    // 是否启用（1:启用，0:禁用）
    @SerialName("enabled")
    val enabled: Int
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class CirclePageDto(
    val id: String,
    val title: String,
    val isActive: Int,
    val pics: List<String>,
    val city: String
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class CircleDetail(
    var id: String,
    var title: String,
    var description: String? = null,
    var area: Double? = null,
    var latitude: Double,
    var longitude: Double,
    var points: List<Position>,

    var city: String,
    var cityCode: String,
    var spotCnt: Int? = null,
    var maintainerCnt: Int? = null,
    var pics: List<String>,

    var createdAt: String,
    var createdBy: Long,
    var updatedAt: String,

    var updatedBy: Long,
    var isActive: Int
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class AddCircleDto(
    var title: String,
    var description: String? = null,
    var latitude: Double,
    var longitude: Double,
    var points: List<Position>,
    var pics: List<String>,
)

@OptIn(InternalSerializationApi::class)
@Serializable
data class SpotInCircleDto(
    val id: String,
    val latitude: Double?,
    val longitude: Double?,
    val name: String?,
    val city: String?,
    val isPrivate: Int?,
    val isFree: Int?
)
